package main

import (
	"fmt"
	"git.oschina.net/xiaoqiaotq/hello-go/cmdb"
	"git.oschina.net/xiaoqiaotq/hello-go/util"
	"github.com/urfave/cli"
	"os"
	"reflect"
	"unicode"
)

func main() {
	output := "json"

	app := cli.NewApp()
	app.Name = "cmdb"
	app.Usage = "cmdb cli"
	app.Version = "v1.0.1"
	app.Author = "wyy29924@ly.com"

	app.Action = func(c *cli.Context) error {
		fmt.Printf("Helloee %q", c.Args().Get(0))
		fmt.Println("----------------------------------------------")
		return nil
	}
	app.Flags = []cli.Flag{
		cli.StringFlag{
			Name:        "output",
			Usage:       `The formatting style for command output. default is json, support : [json ,text] `,
			Destination: &output,
		},
	}
	app.Commands = []cli.Command{
		{
			Name:  "server",
			Usage: "server query",
			Action: func(c *cli.Context) error {
				//output := getOutput(output)
				flags := c.NumFlags()
				fmt.Println("flags is ", flags)
				isQueryNetworkSegment := c.Bool("networkSegment")
				if flags == 0 || (flags == 1 && isQueryNetworkSegment) {
					// query self
					// TODO get self ip
					ip := util.GetOutboundIP().String()
					fmt.Println("query self: ", c.Args().First())
					cmdb.GetServer(ip, "", "", "")
				} else {
					fmt.Println("query option: ", c.GlobalFlagNames())
					servers := cmdb.GetServer("", c.String("sn"), c.String("name"), c.String("asset"))

					printResult(util.InterfaceSlice(servers), getOutput(output))
				}
				fmt.Println("sn is ", c.String("sn") == "")
				fmt.Println("asset is ", c.String("asset"))
				fmt.Println("name is ", c.String("name"))
				fmt.Println("networkSegment is ", isQueryNetworkSegment)
				return nil
			},
			Flags: []cli.Flag{
				cli.StringFlag{
					Name:  "sn",
					Usage: "service tag e.g. 9YHJF3X ",
					//Destination: &sn,
				},
				cli.StringFlag{
					Name:  "name",
					Usage: "server name e.g. TCWEB028",
				},
				cli.StringFlag{
					Name:  "asset",
					Usage: "server asset e.g. FWQ-0332 ",
				},
				cli.BoolFlag{
					Name:  "networkSegment",
					Usage: "query server networkSegment",
				},
			},
		},
		{
			Name:  "vip",
			Usage: "vip query",
			Action: func(c *cli.Context) error {
				vips := cmdb.GetVip(c.Args().First())
				printResult(util.InterfaceSlice(vips), getOutput(output))
				return nil
			},
		},
		{
			Name:  "networkSegment",
			Usage: "networkSegment query",
		},
	}

	app.Run(os.Args)
}

func printStruct(anyStruct interface{}) string {
	structVal := reflect.ValueOf(anyStruct)
	structType := reflect.TypeOf(anyStruct)
	if structVal.Kind() == reflect.Struct {
		nField := structVal.NumField()
		for i := 0; i < nField; i++ {
			f := structVal.Field(i)
			fmt.Printf("%s : %v \n", camel(structType.Field(i).Name), f.Interface())
		}
	}
	return ""
}

func camel(word string) string {
	bytes := make([]byte, len(word))
	for i := 0; i < len(word); i++ {
		if i == 0 {
			if unicode.IsUpper(rune(word[i])) {
				bytes[i] = word[i] + 32
				continue
			}
		}
		bytes[i] = word[i]
	}
	return string(bytes)
}

func getOutput(input string) string {
	format := []string{"json", "text"}
	if contains(format, input) {
		return input
	} else {
		return "json"
	}
}

func contains(s []string, e string) bool {
	for _, a := range s {
		if a == e {
			return true
		}
	}
	return false
}

func printResult(any []interface{}, output string) {
	if reflect.ValueOf(any).Kind() == reflect.Slice {
		if output == "json" {
			json, _ := util.ToJson(any, true)
			fmt.Println(json)
		} else {
			for _, value := range any {
				printStruct(value)
				fmt.Println()
			}
		}
	}
}
